package com.kye.express.business.deposit_recharge.offline;

import android.Manifest;
import android.app.Dialog;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.databinding.DataBindingUtil;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.design.widget.BottomSheetDialog;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.GridLayoutManager;
import android.text.TextUtils;
import android.view.MotionEvent;
import android.view.View;

import com.jakewharton.rxbinding2.view.RxView;
import com.jakewharton.rxbinding2.widget.RxTextView;
import com.kye.base.DebounceObservableTransformer;
import com.kye.base.Logger;
import com.kye.express.R;
import com.kye.express.business.base.BaseToolbarActivity;
import com.kye.express.business.deposit.model.EventBusMsgModel;
import com.kye.express.business.login.LoginActivity;
import com.kye.express.databinding.ActivityRechargeOfflineBinding;
import com.kye.express.utils.ActivityManager;
import com.kye.express.utils.ImageUtils;
import com.kye.express.utils.InputUtils;
import com.kye.express.utils.NetUtils;
import com.kye.express.view.KyeProgressDialog;
import com.kye.express.view.ToastManager;
import com.kye.model.SharedPreferencesConfig;
import com.kye.model.SharedPreferencesManager;
import com.kye.model.bean.OpenApiResult;
import com.kye.model.bean.deposit.ResultIsNeedTicketBean;
import com.kye.model.bean.deposit.ResultUploadVoucherBean;
import com.kye.model.bean.user.User;
import com.kye.model.constant.Constants;
import com.tbruyelle.rxpermissions2.RxPermissions;
import com.zhihu.matisse.Matisse;
import com.zhihu.matisse.MimeType;
import com.zhihu.matisse.engine.impl.GlideEngine;
import com.zhihu.matisse.internal.entity.CaptureStrategy;

import org.greenrobot.eventbus.EventBus;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observer;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import me.drakeet.multitype.Items;
import me.drakeet.multitype.MultiTypeAdapter;

/**
 * 预存运费-充值（线下） Activity
 * <p>
 * Created by SkyYu on 2018/1/18
 */
public class RechargeOfflineActivity extends BaseToolbarActivity implements RechargeOfflineContract.RechargeOfflineView {

    private static final String TAG = RechargeOfflineActivity.class.getSimpleName();

    protected ActivityRechargeOfflineBinding mBinding;
    protected RechargeOfflineContract.RechargeOfflinePresenter mPresenter;
    protected RxPermissions mPermissions;
    protected MultiTypeAdapter mAdapter;
    protected Dialog mDialog;

    protected Items mPictureList;
    protected User mUserInfo;

    public static void startActivity() {
        ActivityManager.getInstance().getCurrentActivity().startActivity(new Intent(ActivityManager.getInstance().getCurrentActivity(), RechargeOfflineActivity.class));
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initView();
        initData();
        initEvents();
    }

    @Override
    protected void onResume() {
        super.onResume();
        mPresenter.bind(this);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (null != mPresenter) mPresenter.unbind();
    }

    /**
     * 点击空白收回键盘
     */
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            InputUtils.hideSoftInput(RechargeOfflineActivity.this);
        }
        return super.dispatchTouchEvent(ev);
    }

    private void initView() {
        initBinding();
        initTitle();
    }

    private void initBinding() {
        mBinding = DataBindingUtil.setContentView(this, R.layout.activity_recharge_offline);
    }

    private void initTitle() {
        setUpToolbar(mBinding.toolbarRechargeOffline);
        setTitle(getString(R.string.depositfreight_rechange));
    }

    private void initData() {
        initPresenter();
        initAdapter();
        init();
        addPlaceholderImage();
        reloadAccount();
    }

    private void initPresenter() {
        mPresenter = new RechargeOfflineContract.RechargeOfflinePresenter();
        mPresenter.bind(this);
    }

    private void initAdapter() {
        mAdapter = new MultiTypeAdapter();
        mAdapter.register(RechargeOfflineImagesModel.class, new RechargeOfflineImageItemViewBinder(this));
        mBinding.recyclerviewOffline.setLayoutManager(new GridLayoutManager(this, 3));
        mBinding.recyclerviewOffline.setHasFixedSize(true);
        mBinding.recyclerviewOffline.setNestedScrollingEnabled(false);
        mBinding.recyclerviewOffline.setItemAnimator(new DefaultItemAnimator());
        mBinding.recyclerviewOffline.setAdapter(mAdapter);
    }

    private void init() {
        mPermissions = new RxPermissions(this);
        mPictureList = new Items();
    }

    private void initEvents() {
        RxView.clicks(mBinding.textviewRechargeOfflineDelete)
                .compose(this.bindToLifecycleDestroy())
                .compose(new DebounceObservableTransformer<>())
                .subscribe((Object) ->
                        mBinding.relativelayoutRechargeOfflineHine.setVisibility(View.GONE)
                );

        RxView.clicks(mBinding.buttonRechargeOfflineSubmit)
                .compose(this.bindToLifecycleDestroy())
                .compose(new DebounceObservableTransformer<>())
                .subscribe((Object) -> {
                    // 请求前先判断网络类型，避免无意义的网络请求
                    if (NetUtils.isNetworkAvailable(this)) {
                        checkAndRequest();
                    } else {
                        ToastManager.show(this, getString(R.string.common_net_error));
                    }
                });

        RxTextView.editorActionEvents(mBinding.edittextRechargeOfflineInput)
                .subscribeOn(AndroidSchedulers.mainThread())
                .observeOn(Schedulers.computation())
                .compose(this.bindToLifecycleDestroy())
                .filter((textViewEditorActionEvent) ->
                        !TextUtils.isEmpty(mBinding.edittextRechargeOfflineInput.getText().toString())
                )
                .map((textViewEditorActionEvent) ->
                        mBinding.edittextRechargeOfflineInput.getText().toString()
                )
                .doOnNext((string) ->
                        Logger.d("input : " + string)
                )
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<String>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(String queryData) {
                        Logger.d(queryData);
                        InputUtils.hideSoftInput(RechargeOfflineActivity.this);
                    }

                    @Override
                    public void onError(Throwable e) {
                        InputUtils.hideSoftInput(RechargeOfflineActivity.this);
                    }

                    @Override
                    public void onComplete() {
                    }
                });
    }

    @Override
    public void onUserLoad(User user) {
        isLogin(user);
    }

    @Override
    public void onUploadVoucherLoading() {
        showDialog();
    }

    @Override
    public void onUploadVoucherComplete() {
        closeDialog();
    }

    @Override
    public void onUploadVoucherSuccess(OpenApiResult<ResultUploadVoucherBean> result) {
        if (result != null) {
            if (result.getCode() == Constants.ResponseCode_SUCCESS) {
                ToastManager.show(this, "保存成功");
                EventBus.getDefault().post(new EventBusMsgModel(EventBusMsgModel.TYPE_REFRESH));
                Single.timer(1, TimeUnit.SECONDS)
                        .compose(this.bindToLifecycle())
                        .subscribe((Long) ->
                                        finish()
                                , Throwable::printStackTrace
                        );
            } else {
                ToastManager.show(this, result.getMsg());
            }
        } else {
            Logger.d(TAG + " - onUploadVoucherSuccess - result is null");
        }
    }

    @Override
    public void onUploadVoucherApiError(OpenApiResult<ResultUploadVoucherBean> result, int code, String msg) {
        ToastManager.show(this, msg);
        Logger.d(TAG + " - onUploadVoucherApiError - result:" + result + ",code:" + code + ",msg:" + msg);
    }

    @Override
    public void onUploadVoucherOtherError(Throwable e) {
        ToastManager.show(this, getString(R.string.common_net_error));
        Logger.d(TAG + " - onUploadVoucherOtherError : " + e.getMessage());
        e.printStackTrace();
    }

    private void isLogin(User user) {
        if (user == null || !user.isLogin()) {
            ToastManager.show(this, "请先登录");
            LoginActivity.startActivity(this);
        } else {
            mUserInfo = user;
            mBinding.setData(user);
        }
    }

    private void showDialog() {
        mDialog = KyeProgressDialog.show(this, mDialog);
        KyeProgressDialog.show(this, mDialog);
    }

    private void closeDialog() {
        KyeProgressDialog.dismiss(mDialog);
    }

    public void addPlaceholderImage() {
        if (mPictureList.size() <= 2) {
            String item = "";
            mPictureList.add(new RechargeOfflineImagesModel(item, true, false));
            mAdapter.setItems(mPictureList);
        }
    }

    public void deletePlaceholderImage() {
        if (mPictureList.size() > 0) {
            for (int i = 0; i < mPictureList.size(); i++) {
                RechargeOfflineImagesModel model2 = (RechargeOfflineImagesModel) mPictureList.get(i);
                if (mPictureList.size() >= 1 && model2.getUrl().equals("")) {
                    this.mPictureList.remove(i);
                }
            }
        } else {
            String item = "";
            mPictureList.add(new RechargeOfflineImagesModel(item, true, false));
            mAdapter.setItems(mPictureList);
        }
    }

    private void addImageSelected(List<String> pathResult) {
        for (String item : pathResult) {
            mPictureList.add(new RechargeOfflineImagesModel(item, false, true));
        }
    }

    public void showBottomSheet() {
        BottomSheetDialog dialog = new BottomSheetDialog(this);
        dialog.setContentView(R.layout.bottom_sheet_recharge_offline);

        View mSheetView = dialog.getDelegate().findViewById(android.support.design.R.id.design_bottom_sheet);
        if (mSheetView != null) {
            mSheetView.setBackgroundColor(getResources().getColor(R.color.transparent));
        }

        View mCameraView = dialog.findViewById(R.id.relativelayout_sheet_recharge_offline_camera);
        if (mCameraView != null) {
            mCameraView.setOnClickListener(View -> {
                dialog.dismiss();
                permissionForCamera();
            });
        }
        View mViewAlbum = dialog.findViewById(R.id.relativelayout_sheet_recharge_offline_album);
        if (mViewAlbum != null) {
            mViewAlbum.setOnClickListener(View -> {
                dialog.dismiss();
                judgeCondition();
            });
        }
        View mViewCancel = dialog.findViewById(R.id.relativelayout_sheet_recharge_offline_cancel);
        if (mViewCancel != null) {
            mViewCancel.setOnClickListener(View ->
                    dialog.dismiss()
            );
        }

        dialog.show();
    }

    public void judgeCondition() {
        if (mPictureList.size() >= 3) {
            boolean isPlaceHolder = false;
            for (Object items : mPictureList) {
                RechargeOfflineImagesModel model = (RechargeOfflineImagesModel) items;
                if (model.getUrl().equals("")) {
                    isPlaceHolder = true;
                }
            }
            if (isPlaceHolder) {
                permissionForPhoto();
            } else {
                ToastManager.show(this, getString(R.string.president_online_max_image_size));
            }
        } else {
            permissionForPhoto();
        }
    }

    private void permissionForCamera() {
        boolean isPermissionsGranted = mPermissions.isGranted(Manifest.permission.CAMERA) && mPermissions.isGranted(Manifest.permission.WRITE_EXTERNAL_STORAGE);
        if (!isPermissionsGranted) {
            mPermissions
                    .request(Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                    .subscribe(granted -> {
                        if (granted) {
                            selectCamera();
                        } else {
                            ToastManager.show(this, "请授权");
                        }
                    }, Throwable::printStackTrace);
        } else {
            selectCamera();
        }
    }

    private void permissionForPhoto() {
        boolean isPermissionsGranted = mPermissions.isGranted(Manifest.permission.WRITE_EXTERNAL_STORAGE) && mPermissions.isGranted(Manifest.permission.WRITE_EXTERNAL_STORAGE);
        if (!isPermissionsGranted) {
            mPermissions
                    .request(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA)
                    .subscribe(granted -> {
                        if (granted) {
                            selectPhotos();
                        } else {
                            ToastManager.show(this, "请授权");
                        }
                    }, Throwable::printStackTrace);
        } else {
            selectPhotos();
        }
    }

    private void selectCamera() {
        startActivityForResult(new Intent(Constants.ACTION_IMAGE_CAPTURE), Constants.REQUEST_CODE_CAMERA);
    }

    private void selectPhotos() {
        Matisse.from(this)
                .choose(MimeType.ofAll(), false)
                .theme(R.style.Matisse_Dracula)
                .countable(true)
                .capture(true)
                .captureStrategy(new CaptureStrategy(true, getApplication().getPackageName() + ".fileprovider"))
                .maxSelectable(3)
                .restrictOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
                .thumbnailScale(0.85f)
                .imageEngine(new GlideEngine())
                .forResult(Constants.REQUEST_CODE_ALBUM);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case Constants.REQUEST_CODE_CAMERA:
                if (resultCode == RESULT_OK) {
                    handleCameraImage(data);
                }
                break;
            case Constants.REQUEST_CODE_ALBUM:
                if (resultCode == RESULT_OK) {
                    handleAlbumImage(data);
                }
                break;
            default:
                break;
        }
    }

    private void handleCameraImage(Intent data) {
        Bundle bundle = data.getExtras();
        if (bundle != null) {
            Bitmap bitmap = (Bitmap) bundle.get("data");
            Uri uriPath = Uri.parse(MediaStore.Images.Media.insertImage(getContentResolver(), bitmap, null, null));
            String filePath = ImageUtils.uriPathConvertFilePath(getApplicationContext(), uriPath);
            RechargeOfflineImagesModel model = (RechargeOfflineImagesModel) mPictureList.get(0);
            if (model.getUrl().equals("")) {
                mPictureList.remove(0);
            }
            List<String> list = new ArrayList<>();
            list.add(filePath);
            addImageSelected(list);
            deletePlaceholderImage();
            addPlaceholderImage();
            mAdapter.notifyDataSetChanged();
        } else {
            Logger.d("bundle is null");
        }
    }

    private void handleAlbumImage(Intent data) {
        List<String> pathResult = Matisse.obtainPathResult(data);
        if (pathResult != null && pathResult.size() > 0) {
            addImageSelected(pathResult);
            deletePlaceholderImage();
            addPlaceholderImage();
            mAdapter.notifyDataSetChanged();
        }
    }

    private void reloadAccount() {
        String username = SharedPreferencesManager.get(SharedPreferencesConfig.KEY_RECHARGE_OFFLINE_USERNAME);
        String bankname = SharedPreferencesManager.get(SharedPreferencesConfig.KEY_RECHARGE_OFFLINE_BANKNAME);
        String account = SharedPreferencesManager.get(SharedPreferencesConfig.KEY_RECHARGE_OFFLINE_ACCOUNT);

        ResultIsNeedTicketBean bean = new ResultIsNeedTicketBean(false, account, username, bankname);
        mBinding.textviewRechargeOfflineAccountname.setText(bean.getUserName());
        mBinding.textviewRechargeOfflineBankname.setText(bean.getBankName());
        mBinding.textviewRechargeOfflineAccount.setText(bean.getAccount());
    }


    private void checkAndRequest() {
        // 准备各项参数
        String phone = mUserInfo.getPhone();
        String companyCode = mUserInfo.getLastAddress().get(0).getCompanyCode();
        String companyName = mUserInfo.getLastAddress().get(0).getCompanyName();
        String paymentMoney = mBinding.edittextRechargeOfflineInput.getText().toString();
        List<String> pictureBase64List = new ArrayList<>();

        // 各种判断
        if (TextUtils.isEmpty(phone) && TextUtils.isEmpty(companyCode) && TextUtils.isEmpty(companyName)) {
            ToastManager.show(this, "请先登录");
            return;
        }
        if (TextUtils.isEmpty(paymentMoney)) {
            ToastManager.show(this, "请输入转入金额");
            return;
        }
        if (Integer.parseInt(paymentMoney) < 1000) {
            ToastManager.show(this, "转入金额不能小于1000元");
            return;
        }
        if (mPictureList.size() == 0) {
            ToastManager.show(this, "请从相册选取或拍摄凭证图片");
            return;
        }

        // 过滤占位图
        for (int i = 0; i < mPictureList.size(); i++) {
            String url = ((RechargeOfflineImagesModel) mPictureList.get(i)).getUrl();
            if (url.equals("")) {
                mPictureList.remove(i);
            }
        }
        // 照片字符串地址转成base64
        for (int i = 0; i < mPictureList.size(); i++) {
            Bitmap bitmap = ImageUtils.getBitmap(((RechargeOfflineImagesModel) mPictureList.get(i)).getUrl());
            String base64 = ImageUtils.bitmaptoString(bitmap);
            pictureBase64List.add(base64);
            ImageUtils.recycleBitmap(bitmap);
        }
        // base64字符串List转成字符串数组
        String[] pictureBase64Arr = new String[pictureBase64List.size()];
        pictureBase64List.toArray(pictureBase64Arr);

        // 准备就绪，开始请求
        mPresenter.requestToUploadVoucher(phone, companyCode, companyName, paymentMoney, pictureBase64Arr);
    }
}